#!/bin/bash
set -euo pipefail

SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )"
PLATFORM=$(uname | tr '[:upper:]' '[:lower:]')
TEST_ID=$(uuidgen | cut -d'-' -f1 | tr '[:upper:]' '[:lower:]')
CLUSTER_NAME_BASE=$(uuidgen | cut -d'-' -f1 | tr '[:upper:]' '[:lower:]')
OVERRIDE_PATH=0
KIND_CONFIG_FILE=$SCRIPTPATH/kind-three-node-cluster.yaml
use_psp=false
# shellcheck disable=SC2034
K8_1_32="kindest/node:v1.32.2@sha256:f226345927d7e348497136874b6d207e0b32cc52154ad8323129352923a3142f"
# shellcheck disable=SC2034
K8_1_31="kindest/node:v1.31.2@sha256:18fbefc20a7113353c7b75b5c869d7145a6abd6269154825872dc59c1329912e"
# shellcheck disable=SC2034
K8_1_30="kindest/node:v1.30@sha256:047357ac0cfea04663786a612ba1eaba9702bef25227a794b52890dd8bcd692e"
# shellcheck disable=SC2034
K8_1_29="kindest/node:v1.29.2@sha256:51a1434a5397193442f0be2a297b488b6c919ce8a3931be0ce822606ea5ca245"

K8_VERSION="$K8_1_32"
KUBECTL_VERSION=$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)
KIND_VERSION="0.27.0"
HELM_VERSION="3.17.1"

echoerr() { echo "$@" 1>&2; }

USAGE=$(cat << 'EOM'
  Usage: provision-cluster  [-b <BASE_CLUSTER_NAME>] [-i <TEST_IDENTIFIER>] [-v K8s_VERSION] [-o]
  Executes the spot termination integration test for the Node Termination Handler.
  Outputs the cluster context directory to stdout on successful completion

  Example: provision-cluster -b my-test -i 123 -v 1.32

          Optional:
            -b          Base Name of cluster
            -i          Test Identifier to suffix Cluster Name and tmp dir
            -v          K8s version to use in this test
            -k          Kind cluster config file
            -o          Override path w/ your own kubectl and kind binaries
EOM
)

# Process our input arguments
while getopts "b:i:v:k:o" opt; do
  case ${opt} in
    b ) # BASE CLUSTER NAME
        CLUSTER_NAME_BASE=$OPTARG
      ;;
    i ) # Test ID
        TEST_ID=$OPTARG
        echoerr "👉 Test Run: $TEST_ID 👈"
      ;;
    v ) # K8s version to provision
        maj_ver=`echo $OPTARG | cut -d '.' -f 1`
        min_ver=`echo $OPTARG | cut -d '.' -f 2`
        if [[ $maj_ver -eq 1 && $min_ver -lt 25 ]]; then
          use_psp=true
        fi
        OPTARG="K8_${maj_ver}_${min_ver}"
        if [ ! -z ${OPTARG+x} ]; then
            K8_VERSION=${!OPTARG}
        else
            echoerr "K8s version not supported"
            exit 2
        fi
      ;;
    k ) # Kind cluster config file
        KIND_CONFIG_FILE=$OPTARG
      ;;
    o ) # Override path with your own kubectl and kind binaries
	    OVERRIDE_PATH=1
      ;;
    \? )
        echoerr "$USAGE" 1>&2
        exit
      ;;
  esac
done

CLUSTER_NAME="$CLUSTER_NAME_BASE"-"$TEST_ID"
TMP_DIR=$SCRIPTPATH/../../build/tmp-$CLUSTER_NAME

echoerr "🐳 Using Kubernetes $K8_VERSION"
mkdir -p $TMP_DIR

deps=("docker")

for dep in "${deps[@]}"; do
    path_to_executable=$(which $dep)
    if [ ! -x "$path_to_executable" ]; then
        echoerr "You are required to have $dep installed on your system..."
        echoerr "Please install $dep and try again. "
        exit 3
    fi
done

## Append to the end of PATH so that the user can override the executables if they want
if [[ OVERRIDE_PATH -eq 1 ]]; then
   export PATH=$PATH:$TMP_DIR
else
  if [ ! -x "$TMP_DIR/kubectl" ]; then
      echoerr "🥑 Downloading the \"kubectl\" binary"
      retry 5 curl -Lo $TMP_DIR/kubectl "https://storage.googleapis.com/kubernetes-release/release/$KUBECTL_VERSION/bin/$PLATFORM/amd64/kubectl"
      chmod +x $TMP_DIR/kubectl
      echoerr "👍 Downloaded the \"kubectl\" binary"
  fi

  if [ ! -x "$TMP_DIR/kind" ]; then
      echoerr "🥑 Downloading the \"kind\" binary"
      retry 5 curl -Lo $TMP_DIR/kind https://github.com/kubernetes-sigs/kind/releases/download/v$KIND_VERSION/kind-$PLATFORM-amd64
      chmod +x $TMP_DIR/kind
      echoerr "👍 Downloaded the \"kind\" binary"
  fi

  if [ ! -x "$TMP_DIR/helm" ]; then
      echoerr "🥑 Downloading the \"helm\" binary"
      retry 5 curl -L https://get.helm.sh/helm-v$HELM_VERSION-$PLATFORM-amd64.tar.gz | tar zxf - -C $TMP_DIR
      mv $TMP_DIR/$PLATFORM-amd64/helm $TMP_DIR/.
      chmod +x $TMP_DIR/helm
      echoerr "👍 Downloaded the \"helm\" binary"
  fi
  export PATH=$TMP_DIR:$PATH
fi

# Disable spinners and color in kind output
export TERM=dumb
echoerr "🥑 Creating k8s cluster using \"kind\""
if [[ "$use_psp" = false ]]; then
  no_psp_kind_config_file="${TMP_DIR}/`basename $KIND_CONFIG_FILE`"
  cat $KIND_CONFIG_FILE | sed 's/,PodSecurityPolicy//' > "${no_psp_kind_config_file}"
  KIND_CONFIG_FILE="${no_psp_kind_config_file}"
fi
retry 3 kind create cluster --name "$CLUSTER_NAME" --image $K8_VERSION --config "$KIND_CONFIG_FILE" --kubeconfig $TMP_DIR/kubeconfig 1>&2

echo "$CLUSTER_NAME" > "$TMP_DIR/clustername"
echoerr "👍 Created k8s cluster using \"kind\""

if [[ "$use_psp" = true ]]; then
  kubectl apply -f "$SCRIPTPATH/psp-default.yaml" --context "kind-$CLUSTER_NAME" --kubeconfig "$TMP_DIR/kubeconfig" 1>&2
  kubectl apply -f "$SCRIPTPATH/psp-privileged.yaml" --context "kind-$CLUSTER_NAME" --kubeconfig "$TMP_DIR/kubeconfig" 1>&2
fi

echo "$TMP_DIR"
